package com.xh.bussiness.course.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.course.bean.dto.CourseDto;
import com.xh.bussiness.course.constant.PrepareLessonConstants;
import com.xh.bussiness.course.model.CourseIndex;
import com.xh.bussiness.course.model.PrepareLessonLog;
import com.xh.bussiness.course.model.PrepareLessonScore;
import com.xh.bussiness.course.service.*;
import com.xh.bussiness.course.model.PrepareLesson;
import com.xh.bussiness.course.bean.request.PrepareLessonRequest;
import com.xh.bussiness.resource.bean.dto.MaterialDto;
import com.xh.bussiness.resource.bean.request.MaterialCourseIndexRequest;
import com.xh.bussiness.resource.constant.MaterialType;
import com.xh.bussiness.resource.model.PaperCourseIndex;
import com.xh.bussiness.resource.service.IMaterialCourseIndexService;
import com.xh.bussiness.resource.service.IMaterialPrepareService;
import com.xh.bussiness.resource.service.IPaperCourseIndexService;
import com.xh.bussiness.system.model.Config;
import com.xh.bussiness.system.service.IConfigService;
import com.xh.bussiness.system.service.IGlobalPrepareConfigGroupService;
import com.xh.bussiness.tiku.model.Paper;
import com.xh.core.annotation.ExcludeLoginTokenIntercept;
import com.xh.core.bean.XhExportHeaderBean;
import com.xh.core.util.UserUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import com.xh.core.bean.AjaxResult;
import com.xh.core.bean.XhPage;
import com.xh.core.constant.AjaxResultConstant;
import org.springframework.validation.annotation.Validated;

import com.xh.core.controller.BaseController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Pitt
 * @since 2020-12-15
 */
@RestController
@RequestMapping("/admin/prepareLesson")
public class PrepareLessonController extends BaseController {

    @Autowired
    private IPrepareLessonService prepareLessonService;
    @Autowired
    private ICourseIndexService courseIndexService;
    @Autowired
    private IPrepareLessonScoreService prepareLessonScoreService;
    @Autowired
    private IMaterialCourseIndexService materialCourseIndexService;
    @Autowired
    private IMaterialPrepareService materialPrepareService;
    @Autowired
    private ICourseChapterService courseChapterService;
    @Autowired
    private IPrepareUserConfigService prepareUserConfigService;
    @Autowired
    private IPaperCourseIndexService paperCourseIndexService;

    /**
     * 分页数据查询
     *
     * @param page 分页对象
     * @param bean 查询条件Bean
     * @return
     */
    //旧版需删除
    @PostMapping("/queryPage")
    public XhPage queryPage(XhPage page, PrepareLessonRequest bean) {
        page = prepareLessonService.queryPrepareLessonPage(page, bean);
        return page;
    }

    @RequestMapping("/queryPageV2")
    public AjaxResult queryPageV2(XhPage page, PrepareLessonRequest bean) {
        bean.setCreatorId(UserUtils.getCurrentUserId());
        page = prepareLessonService.queryPrepareLessonPage(page, bean);
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, page);
    }

    /**
     * 数据查询
     *
     * @param bean 查询条件Bean
     * @return
     */
    @PostMapping("/query")
    public AjaxResult query(PrepareLessonRequest bean) {
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, "", prepareLessonService.queryPrepareLesson(bean));
    }

    /**
     * 导出全部
     *
     * @param bean
     * @return
     */
    @PostMapping(value = "/exportAll")
    public AjaxResult exportAll(PrepareLessonRequest bean, HttpServletRequest request) {
        try {
            LinkedHashMap<String, XhExportHeaderBean> exportHeaderBeans = new LinkedHashMap<>();
            //exportHeaderBeans.put("username",new XhExportHeaderBean("用户名"));
            //exportHeaderBeans.put("deleted",new XhExportHeaderBean("是否删除",ImmutableMap.of(0,"否",1,"是")));
            //exportHeaderBeans.put("createTime",new XhExportHeaderBean("创建时间","yyyy-MM-dd HH:mm:ss"));

            String downloadUrl = prepareLessonService.exportAll(request, exportHeaderBeans, bean, "queryPrepareLessonPage");
            if (downloadUrl != null) {
                return new AjaxResult(AjaxResultConstant.Result.SUCCESS, "", downloadUrl);
            } else {
                return new AjaxResult(AjaxResultConstant.Result.ERROR, "导出失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new AjaxResult(AjaxResultConstant.Result.ERROR);
        }
    }

    /**
     * 新增和保存
     *
     * @param prepareLesson 实体对象
     * @return
     */
    @PostMapping(value = "/saveOrUpdate")
    @Transactional
    public AjaxResult saveOrUpdate(@Validated PrepareLesson prepareLesson) {
        if (prepareLesson.getId() == null) {
            prepareLessonService.insert(prepareLesson);
        } else {
            prepareLessonService.update(prepareLesson);
        }
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS);
    }

    /**
     * 删除操作
     *
     * @param id
     * @return
     */
    @PostMapping("/deleteById/{id}")
    @Transactional
    public AjaxResult deleteById(@PathVariable String id) {
        prepareLessonService.delete(id);
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS);
    }

    /**
     * 批量删除操作
     *
     * @param ids
     * @return
     */
    @PostMapping("/batchDelete")
    @Transactional
    public AjaxResult batchDelete(String[] ids) {
        prepareLessonService.batchDelete(ids);
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS);
    }

    @RequestMapping("/queryMaterialCountByCourseIndexId")
    @ApiOperation(value = "根据备课id查询备课资料个数", notes = "根据备课id查询备课资料个数")
    public AjaxResult queryMaterialCountByCourseIndexId(String courseIndexId) {
        // 1、查询公共的
        MaterialCourseIndexRequest materialCourseIndexRequest = new MaterialCourseIndexRequest();
        materialCourseIndexRequest.setCourseIndexId(courseIndexId);
        Map<String, Long> publicMatialCount = materialCourseIndexService.queryMaterialCountByCourseIndex(materialCourseIndexRequest);
        String userId = UserUtils.getCurrentUserId();
        //3、查询个人上传的
        Map<String, Long> privateMaterialCount = courseChapterService.queryMaterialCountByType(userId, courseIndexId);
        //4、查询个人备课的
//        Map<String, Long> prepareMaterialCount = materialPrepareService.queryCountByType(courseIndexId, userId);
        List<PaperCourseIndex> paperCourseIndices = paperCourseIndexService.queryByCourseIndexId(courseIndexId);
        // 三种数据相加
        for (Map.Entry<String, Long> entry : publicMatialCount.entrySet()) {
            String key = entry.getKey();
            publicMatialCount.put(key, entry.getValue() + privateMaterialCount.get(key));
        }
        publicMatialCount.put(MaterialType.PAPER, Long.valueOf(paperCourseIndices.size()));
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, publicMatialCount);
    }

    @ExcludeLoginTokenIntercept
    @RequestMapping("/queryMaterialByCourseIndexId")
    @ApiOperation(value = "根据备课id查询备课资料", notes = "根据备课id查询备课资料")
    public AjaxResult queryMaterialByCourseIndexId(String courseIndexId, Integer type, Integer isPrepareCheck) {
        if (StringUtils.isEmpty(courseIndexId)) {
            return new AjaxResult(AjaxResultConstant.Result.ERROR, "参数错误！");
        }
        // 试卷
        if(type == 7){
            return new AjaxResult(AjaxResultConstant.Result.SUCCESS, paperCourseIndexService.queryPaperByCourseIndex(courseIndexId));
        }
        List<MaterialDto> publicMaterials = new ArrayList<>();
        if (isPrepareCheck == null) {
            // 1、查询公共的
            MaterialCourseIndexRequest materialCourseIndexRequest = new MaterialCourseIndexRequest();
            materialCourseIndexRequest.setCourseIndexId(courseIndexId);
            materialCourseIndexRequest.setType(type);
            List<MaterialDto> materialDtos = materialCourseIndexService.queryMaterialByCourseIndex(materialCourseIndexRequest);
            if (!CollectionUtils.isEmpty(materialDtos)) {
                publicMaterials.addAll(materialDtos);
            }
        }
        String userId = UserUtils.getCurrentUserId();

        //3、查询个人上传的
        List<MaterialDto> privateMaterials = courseChapterService.queryMaterialByCourseIndex(userId, courseIndexId, type);

//        List<Paper> papers = paperCourseIndexService.queryPaperByCourseIndex(courseIndexId);

        publicMaterials.addAll(privateMaterials);

        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, publicMaterials);
    }

    @RequestMapping("/queryPrepareMaterials")
    @ApiOperation(value = "根据课次查询备课上传的资料", notes = "根据课次查询备课上传的资料")
    public AjaxResult queryPrepareMaterials(String teacherId, String courseIndexId) {
        if (StringUtils.isEmpty(courseIndexId)) {
            return new AjaxResult(AjaxResultConstant.Result.ERROR, "参数错误！");
        }
        if(StringUtils.isEmpty(teacherId)){
            teacherId = UserUtils.getCurrentUserId();
        }
        //4、查询个人备课的
        List<MaterialDto> prepareMaterials = materialPrepareService.queryMaterialByCourseIndex(teacherId, courseIndexId, null);
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, prepareMaterials);
    }

    @RequestMapping("/queryPrepareLessonByCourseIndexId")
    public AjaxResult queryPrepareLessonByCourseIndexId(String courseIndexId) {
        CourseIndex courseIndex = courseIndexService.getById(courseIndexId);

        PrepareLesson prepareLesson = prepareLessonService.queryByUserId(UserUtils.getCurrentUserId(), courseIndex.getCourseId(), courseIndex.getId());
        CourseDto courseDto = courseIndexService.queryOne(courseIndexId);

        // 用户备课设置
        String userId = UserUtils.getCurrentUserId();
        String config = prepareUserConfigService.getUserPrepareConfig(userId,  courseIndex.getCourseId());

        Map<String, Object> retMap = new HashMap<>();
        retMap.put("prepareLesson", prepareLesson);
        retMap.put("courseDto", courseDto);
        retMap.put("userPrepareConfig", JSON.parseObject(config));

        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, retMap);
    }

    /**
     * 提交备课
     *
     * @param prepareLessonId
     * @return
     */
    @RequestMapping("/submitPrepareLessonById")
    public AjaxResult submitPrepareLessonById(HttpServletRequest request, String courseId, String courseIndexId, String prepareLessonId) {
        QueryWrapper<PrepareLesson> qw = new QueryWrapper<>();
        qw.eq("creator_id", request.getHeader("userId"));
        qw.eq("course_id", courseId);
        qw.eq("course_index", courseIndexId);
        PrepareLesson prepareLesson = prepareLessonService.selectFirst(qw);
        if (prepareLesson == null) {
            prepareLesson = new PrepareLesson();
            prepareLesson.setCreatorId(request.getHeader("userId"));
            prepareLesson.setCourseId(courseId);
            prepareLesson.setCourseIndex(courseIndexId);
            prepareLessonService.insert(prepareLesson);
        }
        // 新增提交记录
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, prepareLessonService.submitPrepare(prepareLesson));
    }

    @RequestMapping("/savePrepareLessonScore")
    @ApiOperation("保存备课评分")
    public AjaxResult savePrepareLessonScore(@Valid PrepareLessonScore prepareLessonScore) {
        PrepareLesson prepareLesson = prepareLessonService.getById(prepareLessonScore.getPrepareLessonId());
        if (prepareLesson == null) {
            return new AjaxResult(AjaxResultConstant.Result.ERROR, "备课数据不存在");
        }
        prepareLessonScoreService.deleteByPrepareLessonId(prepareLessonScore.getPrepareLessonId());
        boolean insert = prepareLessonScoreService.insert(prepareLessonScore);
        if (insert) {
            prepareLesson.setCheckStatus(2);
            prepareLesson.setScore(prepareLessonScore.getTotalScore());
            prepareLessonService.update(prepareLesson);
        }
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, "保存成功");
    }

    @RequestMapping("/queryPrepareLessonScoreByPreId")
    @ApiOperation("根据备课查询评分详情")
    public AjaxResult queryPrepareLessonScoreByPreId(String prepareLessonId) {
        if (StringUtils.isEmpty(prepareLessonId)) {
            return new AjaxResult(AjaxResultConstant.Result.ERROR, "参数错误！");
        }
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, prepareLessonScoreService.queryByPrepareLessonId(prepareLessonId));
    }
    /**
     * 查询审核结果，包括评分和审核状态
     * @param prepareLessonId
     * @return
     */
    @ExcludeLoginTokenIntercept
    @RequestMapping("/queryCheckResult")
    @ApiOperation("根据备课查询评分和审核结果")
    public AjaxResult queryCheckResult(String prepareLessonId) {
        if (StringUtils.isEmpty(prepareLessonId)) {
            return new AjaxResult(AjaxResultConstant.Result.ERROR, "参数错误！");
        }
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, prepareLessonService.queryCheckResult(prepareLessonId));
    }
    /**
     * 统计最近三十天备课情况
     *
     * @param schoolId
     * @param groupId
     * @return
     */
    @RequestMapping("queryPrepareLessonAnalysis")
    public AjaxResult queryPrepareLessonAnalysis(String subjectCode, String schoolId, String groupId) {
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, prepareLessonService.queryPrepareLessonAnalysis(subjectCode, schoolId, groupId));
    }


    static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    /**
     * 审核备课
     * @param prepareLessonLog
     * @return
     */
    @RequestMapping("checkPrepareLesson")
    public AjaxResult checkPrepareLesson(@RequestBody PrepareLessonLog prepareLessonLog) {
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, prepareLessonService.checkPrepareLesson(prepareLessonLog));
    }

    /**
     * 根据备课id查询操作记录
     * @param prepareLessonId
     * @return
     */
    @RequestMapping("queryPrepareLogs")
    public AjaxResult queryPrepareLogs(String prepareLessonId) {
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, prepareLessonService.queryPrepareLogs(prepareLessonId));
    }

    @RequestMapping("deletePrepareMaterial")
    public AjaxResult deletePrepareMaterial(String courseIndexId, String materialId) {
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, prepareLessonService.deletePrepareMaterial(courseIndexId, materialId));
    }

    @RequestMapping("changePrepareLessonStatus")
    public AjaxResult changePrepareLessonStatus(String prepareLessonId, Integer checkStatus) {
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, prepareLessonService.changePrepareLessonStatus(prepareLessonId, checkStatus));
    }

    /**
     * 查询授课资料：1、查询课次绑定的课件和其他类型资料  2、查询课次绑定的试卷
     * @param courseIndexId
     * @return
     */
    @ExcludeLoginTokenIntercept
    @RequestMapping("/queryTeachingMaterial")
    @ApiOperation(value = "根据备课id查询备课资料", notes = "根据备课id查询备课资料")
    public AjaxResult queryTeachingMaterial(String courseIndexId) {
        if (StringUtils.isEmpty(courseIndexId)) {
            return new AjaxResult(AjaxResultConstant.Result.ERROR, "参数错误！");
        }
        Map<Integer, Object> result = new HashMap();
        // 1、查询公共的课件
        MaterialCourseIndexRequest materialCourseIndexRequest = new MaterialCourseIndexRequest();
        materialCourseIndexRequest.setCourseIndexId(courseIndexId);
        List<MaterialDto> materialDtos = materialCourseIndexService.queryMaterialByCourseIndex(materialCourseIndexRequest);
        if (!CollectionUtils.isEmpty(materialDtos)) {
            for (MaterialDto materialDto : materialDtos) {
                Integer type = materialDto.getType();
                if (type == null) {
                    continue;
                }
//                if(type == 1 || type == 4 || type == 6){
                    List<MaterialDto> materials = result.get(type) == null ? new ArrayList<>() : (List<MaterialDto>) result.get(type);
                    materials.add(materialDto);
                    result.put(type,materials);
//                }
            }
        }
        List<Paper> papers = paperCourseIndexService.queryPaperByCourseIndex(courseIndexId);
        result.put(7, papers);
        return new AjaxResult(AjaxResultConstant.Result.SUCCESS, result);
    }
}

